using System;
using System.Collections.Generic;
using System.Linq;
using Granite.Data;
using LeadTracker.Models;
using System.ComponentModel.DataAnnotations;

namespace LeadTracker.DataAccess
{
	/// <summary>
	/// Data repository for Editor
	/// </summary>
	public class EditorRepository
	{
		private readonly Connection m_Connection;

		/// <summary>
		/// Create a new data repository for Editor
		/// </summary>
		/// <param name="connection">Connection for making database/service calls</param>
		public EditorRepository(Connection connection)
		{
			m_Connection = connection;
		}

		/// <summary>
		/// Saves a new Editor. If the storage logic modifies values, the editor will be updated.
		/// </summary>
		/// <param name="editor">This is a editor containing the new values</param>
		public void Insert(EditorModel editor, int auditUserKey, Connection connection = null)
		{

			if (editor.HasErrors)
				throw new ValidationException("Editor has validation errors");

			var cmd = new ProcedureCall("dbo.EditorInsertModel");
			cmd.Parameters.AutoPopulate("Insert", editor);
			cmd.Add("Audit_UserKey", auditUserKey);
			editor.Update((connection ?? m_Connection).ExecuteRow(cmd));
		}

		/// <summary>
		/// Updates an existing Editor. If the storage logic also modifies values, the editor will be updated.
		/// </summary>
		/// <param name="editor">This is a editor containing the complete set of values</param>
		/// <remarks>Partial updates cannot be performed via this method.</remarks>
		public void Update(EditorModel editor, int auditUserKey, Connection connection = null)
		{
			if (editor.HasErrors)
				throw new ValidationException("Editor has validation errors");

			var cmd = new ProcedureCall("dbo.EditorUpdateModel");
			cmd.Parameters.AutoPopulate("Update", editor);
			cmd.Add("Audit_UserKey", auditUserKey);
			editor.Update((connection ?? m_Connection).ExecuteRow(cmd));
		}


		/// <summary>
		/// Overwrites any changes in a Editor with what is stored in the database. 
		/// </summary>
		/// <param name="editor">This is a editor to be filled.</param>
		/// <remarks>Only the fields labled with Action("Select") are needed.</remarks>
		public void Reload(EditorModel editor, int auditUserKey, Connection connection = null)
		{
			var cmd = new ProcedureCall("dbo.EditorSelecteModel");
			cmd.Parameters.AutoPopulate("Select", editor);
			cmd.Add("Audit_UserKey", auditUserKey);
			editor.Update((connection ?? m_Connection).ExecuteRow(cmd));
		}

		/// <summary>
		/// Deleted the indicated Editor.
		/// </summary>
		/// <param name="editor">Primary key of a Editor to be deleted.</param>
		public void DeleteEditor(int? editorKey, int auditUserKey, Connection connection = null)
		{
			var cmd = new ProcedureCall("dbo.EditorDelete");
			cmd.Add("EditorKey", editorKey);
			cmd.Add("Audit_UserKey", auditUserKey);
			(connection ?? m_Connection).ExecuteNonQuery(cmd);
		}

		/// <summary>
		/// Loads the indicated Editor.
		/// </summary>
		/// <param name="editor">Primary key of a Editor to be loaded.</param>
		public EditorModel SelectEditor(int? editorKey, int auditUserKey, Connection connection = null)
		{
			var cmd = new ProcedureCall("dbo.EditorSelectModel");
			cmd.Add("EditorKey", editorKey);
			cmd.Add("Audit_UserKey", auditUserKey);
			return new EditorModel((connection ?? m_Connection).ExecuteRow(cmd));
		}

		/// <summary>
		/// Selects all of the rows for use in a drop-down list
		/// </summary>
		/// <returns></returns>
		public List<EditorToken> SelectTokens(int auditUserKey, Connection connection = null)
		{
			var cmd = new ProcedureCall("dbo.EditorSelectAllTokens");
			cmd.Add("Audit_UserKey", auditUserKey);
			var table = (connection ?? m_Connection).ExecuteTable(cmd);
			var result = new List<EditorToken>();
			foreach (var row in table)
				result.Add(new EditorToken(row));
			return result;
		}
	}
}

